package com.healthcloud.utils;

import cn.hutool.core.bean.BeanUtil;
import com.google.gson.Gson;
import com.healthcloud.dto.vo.UserTokenVO;
import com.healthcloud.entity.SysUserEntity;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Jwt工具类
 *
 * @author wangdi
 * @date 2018/10/13
 */
@Slf4j
public class JwtUtil {
    private static final String USERNAME = "username";

    private JwtUtil() {

    }

    public static String doGenerateToken(SysUserEntity user, String idCard) {
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtConstant.USERNAME, user.getUsername());
        claims.put(JwtConstant.USER_ID, user.getId());
        claims.put(JwtConstant.ID_CARD, idCard);
        return doGenerateToken(claims);
    }


    private static String doGenerateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(GsonUtil.obj2Json(claims))
                .signWith(SignatureAlgorithm.HS256, JwtConstant.SECRET)
                .compact();
    }


    private static Claims getClaimFromToken(String token) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(JwtConstant.SECRET)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            log.error("token已过期", e);
            e.printStackTrace();
        } catch (UnsupportedJwtException e) {
            e.printStackTrace();
        } catch (MalformedJwtException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }

        return claims;
    }

    /**
     * 从token中获得username
     *
     * @param token
     * @return
     */
    public static String getUsernameFromToken(String token) {
        return String.valueOf(getClaimFromToken(token).get(JwtConstant.USERNAME));
    }
    public static String getUserIdFromToken(String token) {
        return String.valueOf(getClaimFromToken(token).get(JwtConstant.USER_ID));
    }
    public static String getIdCardFromToken(String token) {
        return String.valueOf(getClaimFromToken(token).get(JwtConstant.ID_CARD));
    }
    public static String GetAccountTypeFromToken(String token){
        return String.valueOf(getClaimFromToken(token).get(JwtConstant.ACCOUNTTYPE));
    }
    public static  String GetCompanyIdFromToken(String token){
        return String.valueOf(getClaimFromToken(token).get(JwtConstant.COMPANY_ID));
    }


    /**
     * 从token中获得token type
     *
     * @param token
     * @return
     */
    public static int getJwtTypeFromToken(String token) {
        return (int) getClaimFromToken(token).get(JwtConstant.TYPE);
    }

    /**
     * 从request中获得username
     *
     * @param request
     * @return
     */
    public static String getUsernameFromRequest(HttpServletRequest request) {
        return getUsernameFromToken(getTokenFromRequest(request));
    }
    public static  Long GetCompanyIdFromRequest(HttpServletRequest request){
        return  Long.parseLong(GetCompanyIdFromToken(getTokenFromRequest(request)));
    }

    public static Long getUserIdFromRequest(HttpServletRequest request) {
        return Long.parseLong(getUserIdFromToken(getTokenFromRequest(request)));
    }

    public static String getIdCardFromRequest(HttpServletRequest request) {
        return getIdCardFromToken(getTokenFromRequest(request));
    }
    public static  Integer getAccountTypeFromRequest(HttpServletRequest request){
        return  Integer.parseInt(GetAccountTypeFromToken((getTokenFromRequest(request))));
    }

    public static UserTokenVO getUserFromRequest(HttpServletRequest request) {
        Claims claimFromToken = getClaimFromToken(getTokenFromRequest(request));
        UserTokenVO userTokenVO = new UserTokenVO();
        BeanUtil.copyProperties(claimFromToken, userTokenVO);
        log.info("userTokenVO:{}", userTokenVO);
        return userTokenVO;
    }

    /**
     * 从request中获得token type
     *
     * @param request
     * @return
     */
    public static int getJwtTypeFromRequest(HttpServletRequest request) {
        return (int) getClaimFromToken(getTokenFromRequest(request)).get(JwtConstant.TYPE);
    }

    /**
     * 从request中获得token
     *
     * @param request
     * @return
     */
    public static String getTokenFromRequest(HttpServletRequest request) {
        return request.getHeader(JwtConstant.JWT_HTTP_HEADER);
    }


    public static boolean containToken(HttpServletRequest request) {
        return StringUtils.isNotEmpty(request.getHeader(JwtConstant.JWT_HTTP_HEADER));
    }

    /**
     * 校验Token是否有效
     *
     * @param request
     * @return
     */
    public static boolean verifyToken(HttpServletRequest request) {
        return Objects.nonNull(getClaimFromToken(getTokenFromRequest(request)));
    }
}
